home *** CD-ROM | disk | FTP | other *** search
/ The CICA Windows Explosion! / The CICA Windows Explosion! - Disc 2.iso / programr / drdobbs.zip / HELPDIR.C < prev    next >
C/C++ Source or Header  |  1993-07-26  |  3KB  |  94 lines

  1. /* HELPDIR.C -- List all internal files with a Windows .HLP file
  2.    WHIFS = Windows Help Internal File System
  3.    bcc helpdir.c
  4.    Pete Davis, June 1993
  5.    See article on Windows .HLP format in Dr. Dobb's Journal, September 1993
  6. */
  7. #pragma pack(1)
  8. #include <conio.h>
  9. #include <string.h>
  10. #include <stdio.h>
  11. #include <stdlib.h>
  12. #include "whstruct.h"
  13. #define DO_TITLES
  14. #define PAGE_SIZE       1024L        /* 1k pages -- must be long! */
  15.  
  16. void fail(const char *s) { puts(s); exit(1); }
  17.  
  18. int main(int argc, char *argv[]) {
  19.    HELPHEADER         HelpHdr;
  20.    WHIFSBTREEHEADER   WHIFSHdr;
  21.    BTREENODEHEADER    WHIFSNode;
  22.    int                file, aPage, c;
  23.    long               WHIFSStart, FileOffset;
  24.    FILE               *HelpFile;
  25.    
  26.    if ((HelpFile=fopen(argv[1], "rb")) == NULL)
  27.        fail("can't open file");
  28.    
  29.    /* Get Help header, go to WHIFS and get WHIFS Header */
  30.    fread(&HelpHdr, sizeof(HelpHdr), 1, HelpFile);
  31.    if (HelpHdr.MagicNumber != HELP_MAGIC)
  32.        fail("not a Windows help file");
  33.    
  34.    fseek(HelpFile, HelpHdr.WHIFS, SEEK_SET);
  35.    fread(&WHIFSHdr, sizeof(WHIFSHdr), 1, HelpFile);
  36.    
  37.    /* WHIFS starts after the WHIFSHdr */
  38.    WHIFSStart = HelpHdr.WHIFS + sizeof(WHIFSHdr);
  39.    
  40.    file=1;
  41.    /* Goto WHIFS Root */
  42.    fseek(HelpFile, WHIFSStart + (PAGE_SIZE * WHIFSHdr.RootPage), SEEK_SET);
  43.  
  44.    /* Find the first leaf node */
  45.    while (file < WHIFSHdr.NLevels) {
  46.        /* if it's not a leaf, we don't need last 2 fields */
  47.        fread(&WHIFSNode, 4, 1, HelpFile);
  48.        
  49.        /* Find page pointer to first node in index */
  50.        fread(&aPage, sizeof(int), 1, HelpFile);
  51.        fseek(HelpFile, WHIFSStart + (PAGE_SIZE * aPage), SEEK_SET);
  52.        file++;
  53.    }
  54.  
  55. #if defined(DO_MACROS)
  56. {
  57.     extern void do_macros(FILE *HelpFile, long WHIFSStart);
  58.     do_macros(HelpFile, WHIFSStart);
  59. }
  60. #elif defined(DO_PHRASES)
  61. {
  62.     extern void do_phrases(FILE *HelpFile, long WHIFSStart);
  63.     do_phrases(HelpFile, WHIFSStart);
  64. }
  65. #elif defined(DO_TITLES)
  66. {
  67.     extern void do_titles(FILE *HelpFile, long WHIFSStart);
  68.     do_titles(HelpFile, WHIFSStart);
  69. }
  70. #else
  71.    /* Go through linked list of leaf nodes */
  72.    for (;;) {
  73.        if (! fread(&WHIFSNode, sizeof(WHIFSNode)-2, 1, HelpFile))
  74.            break;
  75.     
  76.        /* List all entries in node */
  77.        for (file = 1; file <= WHIFSNode.NEntries; file ++) {
  78.           while (c = fgetc(HelpFile))
  79.                putchar(c);
  80.           fread(&FileOffset, sizeof(FileOffset), 1, HelpFile);
  81.           printf("  \t0x%08X\n", FileOffset);
  82.        }
  83.        
  84.        if (WHIFSNode.NextPage == -1)
  85.           break;
  86.       else
  87.           fseek(HelpFile,WHIFSStart+(WHIFSNode.NextPage*PAGE_SIZE),SEEK_SET);
  88.    } 
  89. #endif
  90.  
  91.    return 1;
  92. }
  93.  
  94.